package com.log4jviewer.ui.preferences.additional;

import static org.hamcrest.Matchers.instanceOf;

import org.eclipse.jface.bindings.keys.ParseException;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
import org.hamcrest.Matcher;
import org.junit.Ignore;
import org.junit.Test;

import utils.swtbot.UITestConstants;

/**
 * @author <a href="mailto:Daniil.Yaroslavtsev@gmail.com">Daniil Yaroslavtsev</a>
 * 
 */
public class LogTableTest extends AbstractAdditionalPageTest {

    protected static final SWTWorkbenchBot BOT = getBot();

    /**
     * Tests that all cells on the first column of Log Table can`t be edit by F2 key or mouse doubleClick. *
     */
    @Test
    public void testLogTableFirstColumnIsNotEditable() {

        TableViewer logTableViewer = ColumnPreferenceView.getTableViewer();

        SWTBotTable logTable = getLogTable();

        boolean isCellEditorActive = false;

        for (int i = 0; i < logTable.rowCount(); i++) {
            logTable.click(i, 0);
            // try to edit cell by F2 key
            logTable.pressShortcut(getKey(SWT.F2));
            waitForCellEditorState(logTableViewer, false);
            isCellEditorActive = logTableViewer.isCellEditorActive();
            assertFalse(isCellEditorActive);

            // try to edit first cell by mouse doubleclick
            logTable.doubleClick(i, 0);
            waitForCellEditorState(logTableViewer, false);
            isCellEditorActive = logTableViewer.isCellEditorActive();
            assertFalse(isCellEditorActive);
        }
    }

    /**
     * Tests that the width of all Log4j-Viewer Table`s columns changes to Log Table`s "Column Width" value. The bot
     * defines new values by cell editor mouseClick activation and alphanumeric keys pressing.
     * 
     * Note that after this test all Log4j-Viewer Table`s columns will have 60 px width.
     * 
     * @throws ParseException
     * 
     */
    @Ignore
    @Test
    public void testLogTableColumnsSizeChanging() throws ParseException {

        TableViewer logTableViewer = ColumnPreferenceView.getTableViewer();
        final int columnWidthToSet = 60;

        SWTBotTable logTable = getLogTable();

        int widthColIndex = logTable.indexOfColumn("Column Width");

        writeToCell(logTableViewer, 0, widthColIndex, Integer.toString(columnWidthToSet),
                UITestConstants.MOUSE_CLICK_ACTIVATION);

        pressApplyButton();
        closePreferencesDialog();

        SWTBotView log4jView = BOT.viewByTitle("Log4j-Viewer");
        log4jView.show();
        log4jView.setFocus();

        Composite log4jViewComposite = (Composite) log4jView.getWidget();

        Matcher matcher = instanceOf(Table.class);
        SWTBotTable mainViewTable = new SWTBotTable((Table) BOT.widget(matcher, log4jViewComposite));

        // TODO: Invalid thread access here
        int mainViewTableColumnWidth = mainViewTable.widget.getColumn(0).getWidth();

        assertTrue(mainViewTableColumnWidth == columnWidthToSet);

    }

    /**
     * Tests that the rows of Log Table moves correctly when "Move Up" or "Move Down" button is pressed.
     * 
     * @throws InterruptedException
     */
    @Test
    public void testTableElementsMovingOnUpDownButtonsClick() throws InterruptedException {

        SWTBotTable logTable = getLogTable();

        String firstColumnTitle = logTable.cell(0, 0); // "Level"
        String secondColumnTitle = logTable.cell(1, 0); // "Category"

        logTable.select(0);
        pressMoveDownButton();

        boolean moveDownBtnWorks = logTable.cell(0, 0).equals(secondColumnTitle)
                && logTable.cell(1, 0).equals(firstColumnTitle);
        assertTrue(moveDownBtnWorks);

        logTable.select(1);
        pressMoveUpButton();

        boolean moveUpBtnWorks = logTable.cell(0, 0).equals(firstColumnTitle)
                && logTable.cell(1, 0).equals(secondColumnTitle);
        assertTrue(moveUpBtnWorks);
    }

    /**
     * Tests that the columns of main view log table moves correctly when "Move Up" or "Move Down" button is pressed.
     * 
     * @throws InterruptedException
     */
    @Test
    public void testLogTableColumnsMovingOnUpDownButtonsClick() throws InterruptedException {

        SWTBotTable logTable = getLogTable();

        String firstItem = logTable.cell(0, 0); // "Level" by default
        String secondItem = logTable.cell(1, 0); // "Category" by default

        logTable.select(0);
        pressMoveDownButton();
        pressApplyButton();

        closePreferencesDialog();

        SWTBotView log4jView = BOT.viewByTitle("Log4j-Viewer");
        log4jView.show();
        log4jView.setFocus();

        Composite log4jViewComposite = (Composite) log4jView.getWidget();

        Matcher matcher = instanceOf(Table.class);
        SWTBotTable mainViewTable = new SWTBotTable((Table) BOT.widget(matcher, log4jViewComposite));

        String firstColumnName = mainViewTable.columns().get(0);
        String secondColumnName = mainViewTable.columns().get(1);

        boolean moveDownBtnWorks = firstColumnName.equals(secondItem)
                && secondColumnName.equals(firstItem);

        assertTrue(moveDownBtnWorks);

        // open closed preferences page
        openAdditionalPreferencesPage();

        // reparse page controls
        findAndParsePageControls();

        getLogTable().select(1);
        pressMoveUpButton();
        pressApplyButton();

        closePreferencesDialog();

        firstColumnName = mainViewTable.columns().get(0);
        secondColumnName = mainViewTable.columns().get(1);

        boolean moveUpBtnWorks = firstColumnName.equals(firstItem)
                && secondColumnName.equals(secondItem);

        assertTrue(moveUpBtnWorks);
    }
}